﻿using System;
using System.Linq;

namespace reDoo.Data
{
    /// <summary>
    /// Base interface for all repositories. Changes should only be persisten if
    /// <see cref="SaveChanges"/> is called. Otherwise all changes must be droped.
    /// </summary>
    /// <typeparam name="TRepositoryType">The type of the items stored in the repository.</typeparam>
    /// <typeparam name="TPrimaryKeyType">The type of the primary key of the repository type.</typeparam>
    public interface IRepository<TRepositoryType, TPrimaryKeyType>
    {
        /// <summary>
        /// Adds the specified item to the data store.
        /// </summary>
        /// <param name="itemToAdd">The item to add.</param>
        void Add(TRepositoryType itemToAdd);

        /// <summary>
        /// Get the item with the specified id from the data store.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        TRepositoryType GetById(TPrimaryKeyType id);

        /// <summary>
        /// Gets all items from the data store.
        /// </summary>
        /// <returns></returns>
        IQueryable<TRepositoryType> GetAll();

        /// <summary>
        /// Finds items specified by the provided filter expression.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        IQueryable<TRepositoryType> Find(Func<TRepositoryType, bool> filter);

        /// <summary>
        /// Deletes the item with the specified id from the data store.
        /// </summary>
        /// <param name="id">The id.</param>
        void DeleteById(TPrimaryKeyType id);

        /// <summary>
        /// Deletes the specified item from the data store.
        /// </summary>
        /// <param name="itemToDelete">The item to delete.</param>
        void Delete(TRepositoryType itemToDelete);

        /// <summary>
        /// Save all changes that were made to the repository since the last save within the current
        /// context.
        /// </summary>
        void SaveChanges();
    }
}